﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using Language.Scc;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;

namespace Language.Syntax.Colouring
{
    internal sealed class Colorer : IClassifier
    {
        #region Private Data
        
        private Stub.Database _database;
        private Preclassifier _preclassifier;

        #endregion Private Data

        #region C-Tor

        public Colorer( IClassificationTypeRegistryService registry, ITextBuffer textBuffer, Connection connection, Stub.Database database )
        {
            _database = database;

            _preclassifier = new Preclassifier( connection, database, textBuffer, registry );
            _preclassifier.NewSnapshotAvailable += _preclassifier_NewSnapshotAvailable;
        }

        #endregion C-Tor

        #region Event Handlers

        private void _preclassifier_NewSnapshotAvailable( SnapshotSpan span )
        {
            System.Diagnostics.Debug.Print( $"[Colourer] New snapshot available: {span}" );
            ClassificationChanged?.Invoke( this, new ClassificationChangedEventArgs( span ) );
        }

        #endregion Event Handlers

        #region IClassifier

        public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;

        public IList<ClassificationSpan> GetClassificationSpans( SnapshotSpan span )
        {
            return _preclassifier.GetClassificationSpans( span );
        }

        #endregion IClassifier
    }

    #region Provider

    [Export( typeof( IClassifierProvider ) )]
    [ContentType( "redscript" )]
    // --- Provides the classification implemented by the Colorer class
    internal sealed class ClassificationProvider : IClassifierProvider
    {
        /// Import the classification registry to be used for getting a reference
        /// to the custom classification type later.
        [Import]
        internal IClassificationTypeRegistryService ClassificationRegistry = null;

        [Import]
        public Connection Connection { get; set; }

        [Import]
        public Stub.Database Database { get; set; }

        IClassifier IClassifierProvider.GetClassifier( ITextBuffer textBuffer )
        {
            //create a single classifier for each buffer.
            Func<Colorer> sc = () => new Colorer( ClassificationRegistry, textBuffer, Connection, Database );
            return textBuffer.Properties.GetOrCreateSingletonProperty( sc );
        }
    }

    #endregion Provider
}
